EF Core met MySQL en forms in ASP.NET Core
Home

EF Core met MySQL en forms in ASP.NET Core

EF Core met MySQL en forms in ASP.NET Core

Formulieren worden gebruikt voor het overbrengen van gegevens van de browser naar de webserver voor verdere verwerking, zoals het opslaan in een database. Hoe je de gegevens opvraagt uit en opslaat in een database is het onderwerp van deze les. Dat wordt ook CRUD verrichtingen genoemd, of Create, Read, Update en Delete operaties.

Video

Lesmateriaal

Lees aandachtig de volgende tutorials. Besteed vooral voldoende aandacht aan het bestuderen van LINQ!

  1. Learn Razor Pages, Using Forms in Razor Pages, 28/10/2020
  2. Saineshwar Bageri, Simple CRUD Operation with Razor Pages, 26 Sep 2017
  3. Entity Framework Tutorial, Linq-to-Entities Query
    1. Meer algemeen over LINQ: LINQ Tutorial
  4. Het uitgewerkte voorbeeld vind je op Bitbucket.

Updaten

We beginnen met de Updating One knop in de ReadingOne Razor Page te implementeren.

  1. De Bll klasse van OrderStatus moet er zo uitzien:
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace BiblioAdmin.Bll
    {
        public partial class OrderStatus
        {
    
            [Required]
            [Column(TypeName = "varchar(255)")]
            public string Name { get; set; }
            [Column(TypeName = "varchar(1024)")]
            public string Description { get; set; }
            [Key]
            [Column(TypeName = "int(11)")]
            public int Id { get; set; }
        }
    }
    
  2. Verwijder alle methoden uit de DBContext klasse en houdt alleen de constructors over:
    using Microsoft.EntityFrameworkCore;
    
    namespace BiblioAdmin.Bll
    {
        public partial class Docent2Context : DbContext
        {
            public Docent2Context()
            {
            }
    
            public Docent2Context(DbContextOptions<Docent2Context> options)
                : base(options)
            {
            }
    
            public virtual DbSet<Book> Book { get; set; }
            public virtual DbSet<Customer> Customer { get; set; }
            public virtual DbSet<Order> Order { get; set; }
            public virtual DbSet<OrderItem> OrderItem { get; set; }
            public virtual DbSet<OrderStatus> OrderStatus { get; set; }
            public virtual DbSet<ShippingMethod> ShippingMethod { get; set; }
    
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                if (!optionsBuilder.IsConfigured)
                {
                }
            }
    
        }
    }
    
  3. We maken een UpdatingOne.cshtml Razor Page in de map Pages/OrderStatus.
  4. In de PageModel klasse in het het code behind bestand UpdatingOne.cshtml.cs voegen we de volgende code toe:
    1. een DbContext property en Constructor Injection toe:
      private readonly Bll.Docent2Context dbContext;
      // voeg constructor toe om geïnjecteerde DBContext 
      // te kunnen binnenkrijgen in deze klasse
      public UpdatingOneModel(Bll.Docent2Context dbContext)
      {
          this.dbContext = dbContext;
      }
    2. een property voor een instantie van OrderStatus Bll klasse
      public Bll.OrderStatus OrderStatus { get; set; }
    3. een property voor een generieke lijst met instanties van de OrderStatus klasse:
      public List<Bll.OrderStatus> OrderStatusList { get; set; }
    4. In de OnGet methode haal met behulp van dbContext de rij uit tabel op die gewijzigd moet worden. Let erop dat deze methode nu een parameter heeft, nl. int? id. Het vraagteken geeft aan dat die optioneel is. We lezen ook alle rijen in uit de tabel:
      public void OnGet(int? id)
      {
          this.OrderStatus = dbContext.OrderStatus.SingleOrDefault(m => m.Id == id);
          OrderStatusList = dbContext.OrderStatus.ToList();
      }
    5. Om gegevens die in het formulier zullen worden ingetypt te binden aan de instantie van de OrderStatus klasse, moeten we de annotatie [BindProperty] toevoegen aan de eigenschap OrderStatus die we daarnet gedeclareerd hebben in de klasse UpdatingOneModel:
      [BindProperty]
      public Bll.OrderStatus OrderStatus { get; set; }
    6. Tenslote moeten we een methode toevoegen om de gegevens die de gebruiker eventueel gewijzigd heeft in de database op te slagen. De gegevens worden verstuurd naar de server op het moment dat de gebruiker op de Update knop drukt. Dat is een submit knop, dus zal er een POST request naar de server gestuurd worden. In de button geven we mee dat de handler voor de POST Submit is. Dus de naam van de methode is onPostSubmit.

      Als de gebruiker de regels niet volgt die met Data Annotations hebben opgelegd, zoals bv [Required], dan keren we terug naar de UpdatingOne pagina en melden de fout. Als er geen fouten werden ingetypt gaan we naar de Index pagina. We testen dit met de methode ModelState.IsValid.

      Vermits deze methode een pagina moet retourneren moeten we als gegevenstype voor de functie ActionResult opgeven.

      public ActionResult OnPostUpdate(Bll.OrderStatus orderStatus)
      {
          if (!ModelState.IsValid)
          {
              // als er een foutief gegeven is ingetypt ga terug
              // de pagina en toon de fout
              return Page(); // return page
          }
          // dbContext.OrderStatus.Update(orderStatus);
          dbContext.OrderStatus.Update(orderStatus);
          dbContext.SaveChanges();
          // keer terug naar de index pagina van OrderStatus
          return RedirectToPage("Index");
      }
  5. In de view, de UpdatingOne.cshtml pagina:
    1. declareren we eerst die id in de @Page directive:
      @page "{id}"
    2. In de view, het UpdatingOne.cshtml bestand voegen we een form element met HTML controlementen toe.
      1. Let op het gebruik van Tag Helpers, meer over Tag Helpers:
        1. asp-for
        2. asp-validation
        3. asp-page
        4. asp-page-handler
      2. De view (UpdatingOne.cshtml) zelf, ziet er als volgt uit:
        @page "{id}"
        @model BiblioAdmin.Pages.OrderStatus.UpdatingOneModel
        @{
        }
        
        <h3>Updating OrderStatus</h3>
        <hr />
        <br />
        <form method="post">
            <fieldset>
                <div>
                    <label asp-for="OrderStatus.Id"></label>
                    <input asp-for="OrderStatus.Id" />
                </div>
                <div>
                    <label asp-for="OrderStatus.Name"></label>
                    <input asp-for="OrderStatus.Name" />
                    <span class="alert-danger" asp-validation-for="OrderStatus.Name"></span>
                </div>
                <div>
                    <label asp-for="OrderStatus.Description"></label>
                    <textarea asp-for="OrderStatus.Description"></textarea>
                </div>
            </fieldset>
            <div>
                <button type="submit" value="Update" asp-page-handler="Update">Update</button>
            </div>
        </form>
        
        
  6. Tenslotte passen we de UpdatinOne link aan in de ReadingOne.cshtml pagina:
    <a href="/OrderStatus/UpdatingOne/@Model.OrderStatus.Id" class="tile">
        <span class="icon-pencil"></span>
        <span class="screen-reader-text">Updating One</span>
    </a>

Delete

  1. Het deleten van een rij uit de tabel gebeurt vanuit de ReadingOne.cshtml pagina.
  2. In de view, de ReadingOne.cshtml pagina wijzigen we de link voor Delete. We gebruiken Tag Helpers om de link te laten genereren. We maken kennis met nog een Tag Helper, de asp-route-id:
    <a asp-page="./ReadingOne" onclick="return confirm('Weet je zeker dat je deze Orderstatus wilt deleten?');"
        asp-page-handler="Delete" asp-route-id="@Model.OrderStatus.Id">Delete</a>
  3. We moeten geen nieuwe Razor Page openen, het deleten van de rij in de tabel gebeurt in het code behind bestand van de ReadingOne pagina, namelijk in de OnGetDelete methode van de ReadingOneModel klasse:
    public ActionResult OnGetDelete(int? id)
    {
        if (id != null)
        {
    
            Bll.OrderStatus orderStatus = new Bll.OrderStatus();
            orderStatus.Id = (int) id;
            dbContext.Remove(orderStatus);
            dbContext.SaveChanges();
            return RedirectToPage("Index");
        }
        return Page();

Insert

Volg dezelfde stappen als voor Update.

  1. Maak een nieuwe Razor Page in de map OrderStatus met de naam InsertingOne.
  2. Pas het model aan:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.RazorPages;
    
    namespace BiblioAdmin.Pages.OrderStatus
    {
        public class InsertingOneModel : PageModel
        {
            private readonly Bll.Docent2Context dbContext;
            // voeg constructor toe om geïnjecteerde DBContext 
            // te kunnen binnenkrijgen in deze klasse
            public InsertingOneModel(Bll.Docent2Context dbContext)
            {
                this.dbContext = dbContext;
            }
    
            [BindProperty]
            public Bll.OrderStatus OrderStatus { get; set; }
            public List<Bll.OrderStatus> OrderStatusList { get; set; }
            public void OnGet()
            {
                OrderStatusList = dbContext.OrderStatus.ToList();
            }
    
            public ActionResult OnPostInsert(Bll.OrderStatus orderStatus)
            {
                if (!ModelState.IsValid)
                {
                    // als er een foutief gegeven is ingetypt ga terug
                    // de pagina en toon de fout
                    return Page(); // return page, nog een nieuwe ingeven
                }
                // dbContext.OrderStatus.Update(orderStatus);
                dbContext.OrderStatus.Add(orderStatus);
                dbContext.SaveChanges();
                // keer terug naar de index pagina van OrderStatus
                return RedirectToPage("Index");
            }
        }
    }
  3. Pas de view aan:
    @page
    @model BiblioAdmin.Pages.OrderStatus.InsertingOneModel
    @{
    }
    
    <h3>Inserting OrderStatus</h3>
    <hr />
    <br />
    <form method="post">
        <fieldset>
            <div>
                <label asp-for="OrderStatus.Name"></label>
                <input asp-for="OrderStatus.Name" />
                <span class="alert-danger" asp-validation-for="OrderStatus.Name"></span>
            </div>
            <div>
                <label asp-for="OrderStatus.Description"></label>
                <textarea asp-for="OrderStatus.Description"></textarea>
            </div>
        </fieldset>
        <div>
            <button type="submit" value="Insert" asp-page-handler="Insert">Insert</button>
        </div>
    </form>
    
    
  4. Pas de InsertingOne link in de Index en de ReadingOne pagina aan:
    <a href="/OrderStatus/InsertingOne" class="tile">
        <span class="icon-plus"></span>
        <span class="screen-reader-text">Inserting One</span>
    </a>
  5. Pas de InsertingOne link aan in de Index pagina van OrderStatus:
    <a href="/OrderStatus/InsertingOne" class="tile">
        <span class="icon-plus"></span>
        <span class="screen-reader-text">Inserting One</span>
    </a>
    
    of met Tag Helpers:
    <a asp-page="./InsertingOne" asp-page-handler="Inserting">Inserting One </a>

Opdracht

Maak de CRUD operaties voor de volgende entiteiten (zonder rekening te houden met foreign key's):

  1. ShippingMethod
  2. OrderStatus
  3. Book
  4. Order
  5. OrderItem

JI
2020-12-08 18:00:44